<?php

/**
 * @desc 请求ERP
 * @author zhangweifeng@shopex.cn 15-7-7 上午11:02
 */
class apioubao_erp_rpc {

    private $_api_url = '';
    private $_flag = '';  // erp 标识
    private $_token = '';  // erp 私钥
    private $_timeout = 10;
    public $task_name = '';

    function __construct() {
        if(!file_exists(ROOT_DIR.'/config/certi.php')) {
            echo "config/certi.php文件不存在";
            exit;
        }
        require(ROOT_DIR.'/config/certi.php');
        if(!isset($request_api_config['token']) || !isset($request_api_config['url'])) {
            echo "config/certi.php文件中必须定义request_api_config数组，数组中必须包括token和url";
            exit;
        }
        $this->_token = $request_api_config['token'];
        $this->_api_url = $request_api_config['url'];
        $this->pxfk_api_url = $customization['api_url'];

    }
    /**
     * @desc ：调用oubao的进销存api
     * @author jeff 2015/09/29 16:11:38
     * @param params
     * @return 返回值类型
    */
    function call_api_oubao($post) {
        $url = $this->_api_url;
        $post['params']['token'] = md5($this->_token);
        $res = $this->_http_post($url, $post);
        return $res;
    }
    /**
     * @desc ：调用帕西菲克api
     * @author lsc 2019年6月24日15:44:24
     * @param params
     * @return 返回值类型
    */
    function call_api_pxfk($post) {
        $urlData = '?';
        $count = count($post);
        $i = 0;
        foreach ($post as $key => $value) {
            if ($i<$count-1) {
                $urlData .= $key.'='.$value.'&';
            }else{
                $urlData .= $key.'='.$value;
            }
            $i++;
        }
        $url = $this->pxfk_api_url;
        $url .= $urlData;
        // $post['params']['token'] = md5($this->_token);
        $res = $this->curl_request($url);
        return $res;
    }
    /**
     * @desc ：调用oubao的进销存api,并直接decode,如果失败，直接输出错误信息(包括语法错误等)
     *如果成功，会在控制台中输出对象信息,包括逻辑错误,sql错误，或者方法名不存在等
     * 如果要调试，请使用dumpJson函数，方便处理unicode编码
     * 因为加入了调试模式，该方法弃用
     * @author jeff 2015/09/29 16:11:38
     * @param showConsole 是否在控制面板中显示json对象
     * @return 返回值类型
    */
    // function call_api_oubao_decode($post) {
    //     $isDebug = $post['isDebug'];
    //     $url = $this->_api_url;
    //     $post['params']['token'] = $this->_token;
    //     $res = $this->_http_post($url, $post);
    //     $r = json_decode($res,true);
    //     if(!$r) {
    //         echo "<b>解析失败,返回结果：</b>：<br />";
    //         echo $res;
    //         exit;
    //     }
    //     if($r['rsp']===false) {
    //         //输出$r['data']['msg']的错误信息
    //         echo "<b>业务逻辑处理失败，返回错误</b>：<br />";
    //         echo $r['data']['msg'];
    //         if($isDebug && function_exists('consoleLog')) {
    //             echo "<br /><b>控制面板中可看到decode对象：<br />";
    //             consoleLog($r);
    //         }
    //         exit;
    //         //$this->splash('error', '', $this->app->_($r['data']['msg']));
    //     }
    //     if($isDebug && function_exists('consoleLog')) {
    //         consoleLog($r);
    //     }
    //     return $r;
    // }

    /**
     * @desc 模拟请求api数据
     * @author zhangweifeng@shopex.cn 15-6-19 下午4:21
     *
     * 调用方式:
     * $erp_caller_obj = kernel::service('apioubao.rpc_erp_request');
     * if ($erp_caller_obj && method_exists($erp_caller_obj, 'xxx')) {
     *      $caller_result = $erp_caller_obj->xxx();
     * }
     */
    //以下方法需要改写，requre_data格式必须改为:
    // array(
    //     'method'=>'xxx',
    //     'params'=>array(),
    // )的格式
    public function erp_caller($request_data, $rpc_id = '') {
        // $params = $request_data;
        $abi_globalconf = app::get('site')->getConf('abi_globalconf');
        if (empty($abi_globalconf['abi_erpapi']['url']) || empty($abi_globalconf['abi_erpapi']['flag']) || empty($abi_globalconf['abi_erpapi']['token'])) {
            return json_encode(array('msg' => "请先在 百威管理-》全局配置 里进行配置！"));
        }
        $this->_api_url = $abi_globalconf['abi_erpapi']['url'];
        $this->_flag = $abi_globalconf['abi_erpapi']['flag'];
        $this->_token = $abi_globalconf['abi_erpapi']['token'];

        $sys_data = array(
            'ver' => 1,
            'type' => 'json', //可选
            'charset' => 'utf-8',
            'timestamp' => time()
        );

        $request_data = array_merge($request_data, $sys_data);
        $request_data['flag'] = $this->_flag;
        $request_data['sign'] = $this->gen_sign($request_data, $this->_token);

        // $res = $this->_http_post($this->_api_url, $request_data, $params, $rpc_id);
        $res = $this->_http_post($this->_api_url, $request_data, $params, $rpc_id);

        return $res;
    }

    /**
     * @desc 生成签名
     * @param type $params
     * @param type $token
     * @return boolean
     */
    private function gen_sign($params, $token) {
        if (!$token) {
            return false;
        }
        return strtoupper(md5(strtoupper(md5($this->assemble($params))) . $token));
    }

    private function assemble($params) {
        if (!is_array($params)) {
            return null;
        }
        ksort($params, SORT_STRING);
        $sign = '';
        foreach ($params AS $key => $val) {
            if (is_null($val)) {
                continue;
            }
            if (is_bool($val)) {
                $val = ($val) ? 1 : 0;
            }
            $sign .= $key . (is_array($val) ? $this->assemble($val) : $val);
        }
        return $sign;
    }

    /**
     * @desc http 进行api  请求
     * @param type $url 请求地址
     * @param type $request_data 请求的参数
     * @param type $params 应用级参数
     * @return boolean
     */
    private function _http_post($url, $request_data, $params=null, $rpc_id=null) {
        // $api_log = kernel::single('abiapilog_logging'); // 记录日志
        // $api_log->task_name = $this->task_name;
        // $rpc_id = $api_log->request_log($request_data['method'], $params, $rpc_id);
        $http = kernel::single('base_httpclient');
        $response = $http->set_timeout($this->_timeout)->post($url, $request_data);

        if ($response === HTTP_TIME_OUT) {
            // $api_log->update(array('status' => 'fail', 'msg' => '请求超时'), $rpc_id);
            return false;
        } else {
            $res_result = json_decode($response, 1);
            if (!empty($res_result['error_response'])) {
                // $api_log->update(array('status' => 'fail', 'msg' => $res_result['error_response']['msg'] . ' ; ' . $res_result['error_response']['sub_msg']), $rpc_id);
            } else {
                // $api_log->update(array('status' => 'success', 'response_json' => $response), $rpc_id);
            }
        }

        return $response;
    }

    //参数1：访问的URL，参数2：post数据(不填则为GET)，参数3：提交的$cookies,参数4：是否返回$cookies
    function curl_request($url,$post='',$cookie='', $returnCookie=0){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        // curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
        // curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        // curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        // curl_setopt($curl, CURLOPT_REFERER, "http://XXX");
        if($post) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
        }
        if($cookie) {
            curl_setopt($curl, CURLOPT_COOKIE, $cookie);
        }
        curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        if (curl_errno($curl)) {
            return curl_error($curl);
        }
        curl_close($curl);
        if($returnCookie){
            list($header, $body) = explode("\r\n\r\n", $data, 2);
            preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
            $info['cookie']  = substr($matches[1][0], 1);
            $info['content'] = $body;
            return $info;
        }else{
            return $data;
        }
    }

    /**
     * 超时时间设置
     */
    public function set_timeout($timeout) {
        $this->_timeout=$timeout;
    }

}
